package com.example.myapplication.net

import android.text.TextUtils
import android.util.Log
import com.example.myapplication.API_URL
import com.example.myapplication.App
import com.example.myapplication.utils.JacksonUtils
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import retrofit2.Retrofit
import retrofit2.converter.jackson.JacksonConverterFactory

class ApiNetwork {

    private val retrofitMap = hashMapOf<Class<*>, Any>()

    /**
     * 返回一个请求代理
     */
    fun <Api> remote(api: Class<Api>, cache: Boolean = true): Api {
        val get = retrofitMap[api]
        if (get != null) {
            return get as Api
        }
        return retrofit(API_URL).create(api).also {
            if (cache) {
                retrofitMap[api] = it as Any
            }
        }
    }

    // 构建一个Retrofit
    fun retrofit(url: String, vararg interceptor: Interceptor): Retrofit {
        // 得到一个OK Client
        // 创建一个Build
        // 设置web链接
        return Retrofit
            .Builder()
            .baseUrl(url)
            .client(defaultClient(*interceptor)) // 设置client
            .addConverterFactory(JacksonConverterFactory.create(JacksonUtils.objectMapper()))// 设置Json解析器
            .build()
    }

    fun client(vararg interceptor: Interceptor): OkHttpClient {
        // 给所有的请求添加一个拦截器
        return OkHttpClient.Builder()
            .also { builder ->
                interceptor.forEach {
                    builder.addInterceptor(it)
                }
            }
            .build()
    }

    fun defaultClient(vararg interceptor: Interceptor): OkHttpClient {
        // 给所有的请求添加一个拦截器
        val list = mutableListOf<Interceptor>()
        list.add(token)
        if (interceptor.isNotEmpty()) {
            list.addAll(interceptor)
        }
        //list.add(log)
        return client(*list.toTypedArray())
    }

    private val log = LogInterceptor()
    private val token = TokenInterceptor()

    class LogInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            val request = chain.request()
            val t1 = System.nanoTime()
            Log.e(
                "Interceptor",
                java.lang.String.format(
                    " ->>  request %s on %s%n%s",
                    request.url(), chain.connection(), request.headers()
                )
            )
            val response = chain.proceed(request)
            val t2 = System.nanoTime()
            Log.e(
                "Interceptor",
                String.format(
                    " <<- response for %s in %.1fms%n%s",
                    response.request().url(), (t2 - t1) / 1e6, response.headers()
                )
            )
            return response
        }
    }

    class TokenInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            // 拿到我们的请求
            val original = chain.request()
            // 重新进行build
            val builder = original.newBuilder()
            val token = App.instance.getToken()
            if (!TextUtils.isEmpty(token)) {
                builder.addHeader("token", token)
            }
            builder.addHeader("Content-Type", "application/json")
            val newRequest = builder.build()
            // 返回
            return chain.proceed(newRequest)
        }
    }

}